package cn.tedu.mall.seckill.timer.job;

import cn.tedu.mall.common.config.PrefixConfiguration;
import cn.tedu.mall.pojo.seckill.model.SeckillSku;
import cn.tedu.mall.pojo.seckill.model.SeckillSpu;
import cn.tedu.mall.seckill.mapper.SeckillSkuMapper;
import cn.tedu.mall.seckill.mapper.SeckillSpuMapper;
import cn.tedu.mall.seckill.service.ISeckillSkuService;
import cn.tedu.mall.seckill.service.ISeckillSpuService;
import cn.tedu.mall.seckill.utils.SeckillCacheUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.math.RandomUtils;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
public class SeckillInitialJob implements Job {
    @Autowired
    private SeckillSkuMapper skuMapper;
    @Autowired
    private SeckillSpuMapper spuMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {

        // 当前方法时缓存预热操作
        // 执行时间时秒杀开始前5分钟,所有获取一个5分钟后的对象
        LocalDateTime time = LocalDateTime.now().plusMinutes(5);
        //查询这个时间所有进行秒杀的商品
        List<SeckillSpu> seckillSpus = spuMapper.findSeckillSpusByTime(time);
        //遍历获得所有spu
        for (SeckillSpu spu : seckillSpus) {
            List<SeckillSku> seckillSkus = skuMapper.findSeckillSkuBySpuId(spu.getSpuId());
            //遍历获得所有sku
            //库存数的预热
            for (SeckillSku sku : seckillSkus) {
                log.info("开始将{}号sku商品库存预热到Redis",sku.getSkuId());
                String skuStockKey = SeckillCacheUtils.getStockKey(sku.getSkuId());
                if(redisTemplate.hasKey(skuStockKey)){
                    // 如果key已经存在,证明已经缓存过,
                    log.info("{}号商品已经缓存过了!",sku.getSkuId());
                }else {
                    stringRedisTemplate.boundValueOps(skuStockKey)
                            .set(sku.getSeckillStock()+"",
                                    10*60*1000+ RandomUtils.nextInt(10000),
                                    TimeUnit.MILLISECONDS);
                    log.info("成功为{}号sku商品预热缓存",sku.getSkuId());
                }
            }
            //预热每个spu商品对应的随机码,随机码会在生成订单前进行验证,以减轻服务器压力
            String randCodeKey = SeckillCacheUtils.getRandCodeKey(spu.getSpuId());
            if(redisTemplate.hasKey(randCodeKey)){
                int randCode = (int)redisTemplate.boundValueOps(randCodeKey).get();
                log.info("{}号spu商品的随机码已经缓存:{}",spu.getSpuId(),randCode);
            }else {
                int randCode = RandomUtils.nextInt(900000)+100000;
                redisTemplate.boundValueOps(randCodeKey)
                        .set(randCode,10*60*1000+RandomUtils.nextInt(10000),TimeUnit.MILLISECONDS);
                log.info("spuId为{}号spu商品的随机码为:{}",spu.getSpuId(),randCode);
            }


        }

    }







































}
